package com.study.aop.theory.proxy;

import com.study.aop.theory.service.KtvService;
import com.study.aop.theory.service.impl.KtvPrincessB;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK动态代理使用 demo
 * 学习文献：
 *      https://www.cnblogs.com/yeyang/p/10087293.html
 *      https://www.jianshu.com/p/84ffb8d0a338
 *
 *
 * 0. 一种是基于接口的代理；另一种则是基于类的代理
 *  0.1、 JDK自带的基于接口Interface的代理
 *  0.2、三方CGLIB,JAVASSIST等字节码处理的类库，是基于Class类来实现代理
 *
 * 1. 通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象，它并不是我们的InvocationHandler类型，
 * 也不是我们定义的那组接口的类型，而是在运行是动态生成的一个对象
 *
 * 2. Proxy代理类的执行过程:
 * Proxy.newInstance() --> Constructor.copy() ----Constructor.newInstance() ----->
 *  $Proxy代理字节类生成 ---> Method.copy()-----> $Proxy.invoke()(目标接口方法调用)
 *  ---> InvocationHandler.invoke() ---> Method.invoke()
 *
 * @author: chenhs
 * @date: Created in 9:30 2020/4/6
 **/
public class DynamicProxyMain {


    public static void main(String[] args) {

        //配置系统属性为true,代理类生成时将自动写入磁盘
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");


        KtvService ktvService = new KtvPrincessB();

        InvocationHandler invocationHandler = new KtvInvocationHandler(ktvService);

        KtvService ktvProxy = (KtvService) Proxy.newProxyInstance(ktvService.getClass().getClassLoader()
                , ktvService.getClass().getInterfaces()
                , invocationHandler);

        ktvProxy.momoSing("Mike");


        //将我们生成的代理类ktvProxy中相关信息打印出来
        String methodList = "";
        for (Method m : ktvProxy.getClass().getDeclaredMethods()) {
            methodList += m.getName() + "    ";
        }
        System.out.println("ktvProxy中的方法：" + methodList);
        System.out.println("ktvProxy的父类：" + ktvProxy.getClass().getSuperclass() + "\n");
        String interfaces = "";
        for (Class<?> i : ktvProxy.getClass().getInterfaces()) {
            interfaces += i.getName() + "   ";
        }
        System.out.println("ktvProxy中实现的接口：" + interfaces + "\n");
    }

}
